#ifndef FILESAVEPLUGIN_HPP
#define FILESAVEPLUGIN_HPP

#include "plugin/IPlugin.hpp"
#include "ILogReceiver.hpp"
#include "Logger.hpp"
#include "LogWorker.hpp"
#include <QObject>
#include <QThread>
#include <QString>
#include <QVariant>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonDocument>
#include <QtGlobal>

/**
 * @brief FileSavePlugin 类实现了 IPlugin 和 ILogReceiver 接口，用于保存日志到文件
 */
class FileSavePlugin : public IPlugin, public ILogReceiver {
    Q_OBJECT

public:
    /**
     * @brief 构造函数，初始化日志文件并注册为 Logger 的日志接收者
     * @param filePath 日志文件的路径
     * @param parent 父对象
     */
    explicit FileSavePlugin(const QString &filePath, QObject *parent = nullptr)
        : IPlugin(parent), saveFilePath(filePath) {

        // 创建 LogWorker 和线程
        logWorker = new LogWorker(filePath);
        logThread = new QThread(this);
        logWorker->moveToThread(logThread);

        // 连接信号和槽，使用 QueuedConnection 确保跨线程通信
        bool connected = connect(this, &FileSavePlugin::newLogMessage,
                                 logWorker, &LogWorker::processLog, Qt::QueuedConnection);
        if(!connected) {
            // 连接失败时的处理（可选）
        }

        connect(logThread, &QThread::finished, logWorker, &QObject::deleteLater);

        // 启动线程
        logThread->start();

        // 将自身添加为 Logger 的日志接收者
        Logger::instance().addLogReceiver(this);
    }

    /**
     * @brief 析构函数，关闭日志文件并移除日志接收者
     */
    ~FileSavePlugin() {
        Logger::instance().removeLogReceiver(this);

        // 停止线程
        logThread->quit();
        logThread->wait();
    }

    // IPlugin 接口实现
    void onStateChanged(ActionWrapper::StateKey key, const QVariant &value) override {
        QString stateKeyName = actionKeyToString(key);
        QString stateValueStr = variantToString(value);
        QString message = QString("State changed: %1 = %2").arg(stateKeyName, stateValueStr);

        // 通过 Logger 记录日志
        Logger::instance().log(QtInfoMsg, __FILE__, __LINE__, __FUNCTION__, message);
    }

    void onActionDispatched(ActionWrapper::ActionType actionType, const QVariant &payload) override {
        QString actionTypeName = actionTypeToString(actionType);
        QString payloadStr = variantToString(payload);
        QString message = QString("Action dispatched: %1 with payload: %2").arg(actionTypeName, payloadStr);

        // 通过 Logger 记录日志
        Logger::instance().log(QtInfoMsg, __FILE__, __LINE__, __FUNCTION__, message);
    }

    // ILogReceiver 接口实现
    void writeLog(QtMsgType type, const QString &file, int line, const QString &function, const QString &msg) override {
        emit newLogMessage(type, file, line, function, msg);
    }

signals:
    /**
     * @brief 信号用于传递日志消息到 LogWorker
     * @param type 日志类型
     * @param file 文件名
     * @param line 行号
     * @param function 函数名
     * @param msg 日志消息
     */
    void newLogMessage(QtMsgType type, QString file, int line, QString function, QString msg);

private:
    QString saveFilePath;
    QThread *logThread;
    LogWorker *logWorker;

    /**
     * @brief 处理 QVariant 类型的值并转换为字符串
     * @param value QVariant 值
     * @return 转换后的字符串
     */
    QString variantToString(const QVariant &value) const {
        switch(value.type()) {
        case QVariant::Invalid:
            return "Invalid";
        case QVariant::Bool:
            return value.toBool() ? "true" : "false";
        case QVariant::Int:
            return QString::number(value.toInt());
        case QVariant::UInt:
            return QString::number(value.toUInt());
        case QVariant::LongLong:
            return QString::number(value.toLongLong());
        case QVariant::ULongLong:
            return QString::number(value.toULongLong());
        case QVariant::Double:
            return QString::number(value.toDouble());
        case QVariant::String:
            return value.toString();
        case QVariant::Char:
            return QString(value.toChar());
        case QVariant::Date:
            return value.toDate().toString(Qt::ISODate);
        case QVariant::Time:
            return value.toTime().toString("HH:mm:ss"); // 标准时间格式
        case QVariant::DateTime:
            return value.toDateTime().toString(Qt::ISODate);
        case QVariant::List:
            return listToString(value.toList());
        case QVariant::Map:
            return mapToString(value.toMap());
        case QVariant::ByteArray:
            return QString::fromUtf8(value.toByteArray().toBase64());
        case QVariant::UserType: {
            if(value.canConvert<QJsonObject>()) {
                QJsonObject jsonObj = value.value<QJsonObject>();
                return jsonObjectToString(jsonObj);
            }
            if(value.canConvert<Basic>()) {
                Basic basic = value.value<Basic>();
                return jsonObjectToString(basic.toJson());
            }

            if(value.canConvert<Synthetic>()) { // 假设有这个类型
                Synthetic synthetic = value.value<Synthetic>();
                return jsonObjectToString(synthetic.toJson()); // 或其他适当的转换方法
            }

            if(value.canConvert<MetaMoldType::MoldType>()) { // 添加对 MoldType 的处理
                MetaMoldType::MoldType moldType = value.value<MetaMoldType::MoldType>();
                return moldTypeToString(moldType);
            }
            return QString("<不可转换的 QVariant 类型 %1>").arg(value.typeName());
        }
        default:
            if(value.canConvert<QString>()) {
                return value.toString();
            } else {
                return QString("<不可转换的 QVariant 类型 %1>").arg(value.typeName());
            }
        }
    }

    QString listToString(const QVariantList &list) const {
        QStringList stringList;
        for(const QVariant &item : list) {
            stringList << variantToString(item);
        }
        return "[" + stringList.join(", ") + "]";
    }

    QString mapToString(const QVariantMap &map) const {
        QStringList stringList;
        for(auto it = map.constBegin(); it != map.constEnd(); ++it) {
            stringList << QString("%1: %2").arg(it.key(), variantToString(it.value()));
        }
        return "{" + stringList.join(", ") + "}";
    }

    QString jsonObjectToString(const QJsonObject &jsonObject) const {
        QJsonDocument doc(jsonObject);
        return QString::fromUtf8(doc.toJson(QJsonDocument::Compact));
    }

    // 辅助方法
    QString actionKeyToString(ActionWrapper::StateKey key) const {
        switch(key) {
        case ActionWrapper::StateKey::Basic:
            return "Basic";
        case ActionWrapper::StateKey::Synthetic:
            return "Synthetic";
        default:
            return "UnknownStateKey";
        }
    }

    QString actionTypeToString(ActionWrapper::ActionType actionType) const {
        switch(actionType) {
        case ActionWrapper::ActionType::InitBasic:
            return "InitBasic";
        case ActionWrapper::ActionType::EditBasic:
            return "EditBasic";
        case ActionWrapper::ActionType::InitModify:
            return "InitModify";
        case ActionWrapper::ActionType::EditModify:
            return "EditModify";
        default:
            return "UnknownActionType";
        }
    }

    /**
     * @brief 将 MetaMoldType::MoldType 转换为字符串
     * @param moldType MetaMoldType::MoldType 枚举值
     * @return 转换后的字符串
     */
    QString moldTypeToString(MetaMoldType::MoldType moldType) const {
        // 使用 QMetaEnum 自动转换
        const QMetaObject &metaObject = MetaMoldType::staticMetaObject;
        int enumIndex = metaObject.indexOfEnumerator("MoldType");
        if (enumIndex != -1) {
            QMetaEnum metaEnum = metaObject.enumerator(enumIndex);
            const char *key = metaEnum.valueToKey(moldType);
            if (key) {
                return QString::fromLatin1(key);
            }
        }
        return QString("UnknownMoldType(%1)").arg(static_cast<int>(moldType));
    }

};

#endif // FILESAVEPLUGIN_HPP
